package un.broker.asysad.client.rules;

import static un.broker.asysad.C_asysad.HSC;
import static un.broker.asysad.C_asysad.ITM;
import static un.broker.asysad.C_asysad.NB1;
import static un.broker.asysad.C_asysad.NB2;
import static un.broker.asysad.C_asysad.NB3;
import static un.broker.asysad.C_asysad.TAR;
import static un.broker.asysad.C_asysad.VEH;

import java.util.HashSet;
import java.util.Iterator;

import so.kernel.client.VisualForm;
import so.kernel.core.KNumberedSubDataSet;
import so.kernel.core.KNumberedSubDocument;
import so.kernel.core.KernelEvent;
import so.kernel.core.Rule;
import un.broker.asysad.D_asysad;
import un.broker.asysad.client.VD_asysad;
import un.broker.asysad.client.VF_Vehicle;
import un.globalConfig.util.GlobalConfigUtilities;

/** <PATCH ID="Vehicle information page" VERSION="4.2.2" TYPE="JM" DATE="Jun 16, 2015" AUTHOR="Leonardo Flores"> **/
public class R_ManageViewVehicleForm extends Rule {
	
	private D_asysad doc;
	private VD_asysad vd;
	private HashSet<String> tariffCodes;
	/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" VERSION="4.2.2" TYPE="JM" DATE="Mar 16, 2016" AUTHOR="Craig(?_?)Ewers"> **/
	private HashSet<String> tariffCodesExceptions;
	/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" /> **/
	
	public R_ManageViewVehicleForm(D_asysad doc, VD_asysad vd) {
		super();
		this.doc = doc;
		this.vd = vd;
		this.tariffCodes = new HashSet<String>();
		/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" VERSION="4.2.2" TYPE="JM" DATE="Mar 16, 2016" AUTHOR="Craig(?_?)Ewers"> **/
		this.tariffCodesExceptions = new HashSet<String>();
		/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" /> **/
		
		// 1. Get tariff codes that enable vehicle page
		String tariffCodes = GlobalConfigUtilities.getProperty("Client.un.asybrk.asysad.vehiclePage.tariff");
		if (tariffCodes != null){
			String[] tariffList = tariffCodes.split(",");
			for (String code : tariffList) if (code != null) this.tariffCodes.add(code.trim());
		}
		
		/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" VERSION="4.2.2" TYPE="JM" DATE="Mar 16, 2016" AUTHOR="Craig(?_?)Ewers"> **/
		// 2. Get tariff codes EXCEPTIONS under tariff headings
		String tariffExceptions =  GlobalConfigUtilities.getProperty("Client.un.asybrk.asysad.vehiclePage.tariffException");
		if (tariffExceptions != null) {
			String[] tariffExList = tariffExceptions.split(",");
			for (String xCode : tariffExList) if (xCode != null) this.tariffCodesExceptions.add(xCode.trim());
		}
		/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" /> **/
	}

	protected void apply(KernelEvent e) {
		boolean isVisible = false;
		
		// 1. Iterate over all items
		KNumberedSubDataSet items = ((KNumberedSubDataSet)this.doc.ds(ITM));
		int totalItems = items.countDocuments();
		for (int i = 1; i <= totalItems; i++){
			KNumberedSubDocument item = items.getDocument(i);
			String tarifCode = item.ds(TAR).ds(HSC).de(NB1).getString("").trim() + item.ds(TAR).ds(HSC).de(NB2).getString("").trim() + item.ds(TAR).ds(HSC).de(NB3).getString("").trim();
			if (isVisibleCode(tarifCode)){
				isVisible = true;
				if (e.getID() == DOCUMENT_VERIFY.getID()) { // In case of document verify, check that exist an entry on vehicle page
					int itemNumber = item.ds(KNumberedDocumentInterface.KEYS_ID).de(KNumberedSubDocument.RNK).getInt(0);

					if (!hasEntry(itemNumber)) {
						String message = MessageFormat.format(lng("Vehicle information is needed for item {0}. Please, add an entry"),itemNumber);
						setError(item.ds(KNumberedDocumentInterface.KEYS_ID).de(KNumberedSubDocument.RNK),message,e);
					} else {
						// Get how many vehicles are needed (from supplementary units)
						KNumberedSubDataSet sups = (KNumberedSubDataSet)item.ds(TAR).ds(SUP);
						KNumberedSubDocument sup = sups.countDocuments() > 0 ? sups.getDocument(1) : null;
						
						// Assumption. if supplementary unit are required for the commodity code, then, it represents how many vehicles contain the declaration item (no fractional amount)
						BigDecimal qty = GlobalConfigUtilities.getBigDecimal(sup.de(QTY),"SUP",BigDecimal.ZERO);
						if (qty.compareTo(BigDecimal.ZERO) > 0) supVsVeh.put(itemNumber,qty.setScale(0,BigDecimal.ROUND_UP).intValue());

					}
				}else {
					break;
				}
			}
		}
		KNumberedSubDataSet vehicles = ((KNumberedSubDataSet)this.doc.ds(VEH));
		int totalVehicles = vehicles.countDocuments();
		doc.setVisibleOperationEvent(R_PRINTOUT_VEHICLE,isVisible);
		if (isVisible && e.getID() == DOCUMENT_VERIFY.getID()) {
			for (int i = 1; i <= totalVehicles; i++){
				KNumberedSubDocument vehicle = vehicles.getDocument(i);
				String vinNumber = vehicle.ds(DocumentInterface.NORMAL_ID).de(CHA).getString("").trim();
				int itemNumber = vehicle.ds(DocumentInterface.NORMAL_ID).de(ITM).getInt(0);
				if (WHITESPACE.matcher(vinNumber).find()) {
					String message = lng("Spaces are not allowed on chassis number [{0}] - Please, correct vehicle entry on line {1}");
					message = MessageFormat.format(message,vinNumber,vehicle.ds(DocumentInterface.KEYS_ID).de(KNumberedSubDocument.RNK).getInt(0));
					KOptionPane.showMessageDialog(DesktopMain.sharedInstance(),message,lng("Error"),KOptionPane.ERROR_MESSAGE);
					e.consume();
				}
				if (!supVsVeh.containsKey(itemNumber)) {
					String message = lng("Item {0} is not a vehicle tariff and is linked with vehicle chassis {1}, please, update your vehicle information");
					message = MessageFormat.format(message,itemNumber,vinNumber);
					KOptionPane.showMessageDialog(DesktopMain.sharedInstance(),message,lng("Error"),KOptionPane.ERROR_MESSAGE);
					e.consume();
				} else supVsVeh.put(itemNumber,supVsVeh.get(itemNumber) - 1);
			}

			// Verify amount of vehicles vs supplementary units
			for (Entry<Integer,Integer> entry : supVsVeh.entrySet()) {
				if (entry.getValue() != 0) {
					DataSet item = items.getDocument(entry.getKey());
					DataSet sup = ((KNumberedSubDataSet)item.ds(TAR).ds(SUP)).getDocument(1);
					int qty = GlobalConfigUtilities.getBigDecimal(sup.de(QTY),"SUP",BigDecimal.ZERO).setScale(0,BigDecimal.ROUND_UP).intValue();
					int qtyVeh = qty - entry.getValue();
					String message = lng("Item {0} has {1} supplementary units and {2} vehicle entries, please, update quantities accordingly");
					message = MessageFormat.format(message,String.valueOf(entry.getKey()),String.valueOf(qty),String.valueOf(qtyVeh));
					KOptionPane.showMessageDialog(DesktopMain.sharedInstance(),message,lng("Error"),KOptionPane.ERROR_MESSAGE);
					e.consume();
				}
			}
		} else if (!isVisible && e.getID() == DOCUMENT_VERIFY.getID()) {
			for (int i = totalVehicles; i > 0; i--) vehicles.deleteDocument(i);
		}

		// 2. Set visibility
		int formCount = this.vd.getVisualFormCount();
		for (int i = 0; i < formCount; i++){
			VisualForm form = this.vd.getVisualFormAt(i);
			if (VF_Vehicle.class.isInstance(form)){
				if (isVisible != this.vd.isFormVisible(form.getName())) {
					this.vd.setFormVisible(form, isVisible);
				}
				break;
			}
		}
	}

	private boolean hasEntry(int itemNumber) {
		KNumberedSubDataSet vehicles = ((KNumberedSubDataSet)this.doc.ds(VEH));
		int totalVehicles = vehicles.countDocuments();
		for (int i = 1; i <= totalVehicles; i++){
			KNumberedSubDocument vehicle = vehicles.getDocument(i);
			if (vehicle.de(ITM).getInt(0) == itemNumber) return true;
		}
		return false;
	}

	private boolean isVisibleCode(String tarifCode) {
		Iterator<String> it = tariffCodes.iterator();
		while (it.hasNext()){
			String visibleCode = it.next();
			/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" VERSION="4.2.2" TYPE="JM" DATE="Mar 16, 2016" AUTHOR="Craig(?_?)Ewers"> **/
			if (tarifCode.startsWith(visibleCode) && !isTariffException(tarifCode)) return true;
		}
		return false;
	}
	
	/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" VERSION="4.2.2" TYPE="JM" DATE="Mar 16, 2016" AUTHOR="Craig(?_?)Ewers"> **/
	public boolean isTariffException(String tarifCode) {
		Iterator<String> it = tariffCodesExceptions.iterator();
		while (it.hasNext()) {
			String tariffEx = it.next();
			if (tarifCode.startsWith(tariffEx)) return true;
		}
 		return false;
	}
	/** <PATCH ID="Disable Vehicle Information Page for specific tariffs" /> **/
}
